/**
 * 
 */
package view;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import model.User;
import model.viewModels.CenterModel;

/**
 * singelton class for the basic-panel, initialized in the constructor of ChessFrame
 */
@SuppressWarnings( "serial" )
public class BasicPanel extends JPanel {

    /**
     * the only instance of this class
     */
    private static BasicPanel instance;

    /**
     * the panel which will contain the differnt views
     */
    private JPanel contentPanel;

    /**
     * button to activate Center-View
     */
    private JButton bCenter;
    /**
     * button to activate Dares-View
     */
    private JButton bDare;
    /**
     * button to activate Matches-View
     */
    private JButton bMatches;
    /**
     * button to activate Archive-View
     */
    private JButton bArchiv;

    /**
     * label for the welcome-information
     */
    private JLabel lWelcome;

    /**
     * label for the actual date
     */
    private JLabel lDate;

    /**
     * reference to the ChessFrame-class
     */
    private ChessFrame chessFrame;

    /**
     * private constructor, calls super() from JPanel
     * 
     * @param frame
     *            reference to the ChessFrame-class
     */
    public BasicPanel( final ChessFrame frame )
    {
	super();
	this.chessFrame = frame;

	setLayout( new GridBagLayout() );

	// welcome/date line
	this.lWelcome = new JLabel();
	this.lDate = new JLabel();

	// --> buttons to navigate the views
	this.bCenter = new JButton( "Center" );
	this.bCenter.setEnabled( false );
	this.bCenter.addActionListener( new ActionListener() {

	    @Override
	    public void actionPerformed( ActionEvent e )
	    {
		setCenterView();
	    }
	} );

	this.bDare = new JButton( "Herausforderungen" );
	this.bDare.addActionListener( new ActionListener() {

	    @Override
	    public void actionPerformed( ActionEvent e )
	    {
		try
		{
		    setDaresView();
		}
		catch ( NoSuchAlgorithmException e1 )
		{
		    e1.printStackTrace();
		}
	    }
	} );

	this.bMatches = new JButton( "Spiele" );
	this.bMatches.addActionListener( new ActionListener() {

	    @Override
	    public void actionPerformed( ActionEvent e )
	    {
		setActGamesView();
	    }
	} );

	this.bArchiv = new JButton( "Archiv" );
	this.bArchiv.addActionListener( new ActionListener() {

	    @Override
	    public void actionPerformed( ActionEvent e )
	    {
		setArchGamesView();
	    }
	} );

	JButton bUpdate = new JButton( "Aktualisieren" );
	bUpdate.addActionListener( new ActionListener() {

	    @Override
	    public void actionPerformed( ActionEvent e )
	    {
		ChessFrame.updateAction();
	    }
	} );

	JButton bExit = new JButton( "Beenden" );
	bExit.addActionListener( new ActionListener() {

	    @Override
	    public void actionPerformed( ActionEvent e )
	    {
		System.exit( 0 );

	    }
	} );

	JPanel pButtons = new JPanel( new GridLayout( 1, 6 ) );
	pButtons.add( this.bCenter );
	pButtons.add( this.bDare );
	pButtons.add( this.bMatches );
	pButtons.add( this.bArchiv );
	pButtons.add( bUpdate );
	pButtons.add( bExit );
	// <-- buttons

	// initiate the contenPanel
	this.contentPanel = new JPanel();

	// add all to this panel
	GridBagConstraints gbc;
	gbc = GBCUtils.getGBC( 0, 0, 3, 1, 1.0, 0.0, GridBagConstraints.HORIZONTAL, new Insets( 0, 5, 0, 0 ) );
	this.add( this.lWelcome, gbc );
	gbc = GBCUtils.getGBC( 3, 0, 2, 1, new Insets( 0, 0, 0, 5 ) );
	gbc.anchor = GridBagConstraints.LINE_END;
	this.add( this.lDate, gbc );

	gbc = GBCUtils.getGBC( 0, 1, 5, 1, GridBagConstraints.HORIZONTAL );
	this.add( pButtons, gbc );

	gbc = GBCUtils.getGBC( 0, 2, 5, 1, 1.0, 1.0, GridBagConstraints.BOTH );
	this.add( this.contentPanel, gbc );
    }

    /**
     * creates exact one instance of this class
     * 
     * @param chessFrame
     *            reference to the ChessFrame-class
     * @return the instance of this class
     */
    public static BasicPanel getInstance( ChessFrame chessFrame )
    {
	if ( instance == null )
	{
	    instance = new BasicPanel( chessFrame );
	}
	return instance;
    }

    /**
     * is called after a successful login, updates the welcome/date line and sets the CenterView
     */
    public final void onLogin()
    {
	User logU = CenterModel.loggedInUser;
	String space = " ";
	String date = logU.getLastLogin().split( space )[0].split( "-" )[2] + "."
		+ logU.getLastLogin().split( space )[0].split( "-" )[1] + "."
		+ logU.getLastLogin().split( space )[0].split( "-" )[0];
	this.lWelcome.setText( "Willkommen " + logU.getFirstName() + space + logU.getLastName()
		+ ", du hast dich zuletzt am " + date + " (" + logU.getLastLogin().split( space )[1].substring( 0, 5 )
		+ " Uhr) eingeloggt." );
	validate();
	this.repaint();

	setCenterView();
    }

    /**
     * updates the shown time
     * 
     * @param calendar
     *            an instance of GregorianCalender which holds the current time
     */
    public final void updateCurrentTime( GregorianCalendar calendar )
    {
	int d = calendar.get( Calendar.DAY_OF_MONTH );

	int mo = calendar.get( Calendar.MONTH ) + 1;
	int y = calendar.get( Calendar.YEAR );
	String sDate = ( ( d < 10 ) ? "0" + d : d ) + "." + ( ( mo < 10 ) ? "0" + mo : mo ) + "." + y;

	int dw = calendar.get( Calendar.DAY_OF_WEEK ) - 1;
	String[] dayNames = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" };

	int h = calendar.get( Calendar.HOUR_OF_DAY );
	int mi = calendar.get( Calendar.MINUTE );
	String sTime = ( ( h < 10 ) ? "0" + h : h ) + ":" + ( ( mi < 10 ) ? "0" + mi : mi ) + " Uhr";

	this.lDate.setText( "[" + sDate + " (" + dayNames[dw] + ") - " + sTime + "]" );
    }

    /**
     * shows the content of the center view
     */
    private void setCenterView()
    {
	this.bCenter.setEnabled( false );
	this.bDare.setEnabled( true );
	this.bMatches.setEnabled( true );
	this.bArchiv.setEnabled( true );

	this.remove( this.contentPanel );
	this.contentPanel = ChessFrame.centerViewPanel;

	GridBagConstraints gbc;
	gbc = GBCUtils.getGBC( 0, 2, 5, 1, 1.0, 1.0, GridBagConstraints.BOTH );
	this.add( this.contentPanel, gbc );

	this.chessFrame.validate();
	this.chessFrame.repaint();
    }

    /**
     * shows the content of the dares view
     * 
     * @throws NoSuchAlgorithmException .
     */
    private void setDaresView() throws NoSuchAlgorithmException
    {
	this.bCenter.setEnabled( true );
	this.bDare.setEnabled( false );
	this.bMatches.setEnabled( true );
	this.bArchiv.setEnabled( true );

	this.remove( this.contentPanel );
	this.contentPanel = ChessFrame.daresViewPanel;

	GridBagConstraints gbc;
	gbc = GBCUtils.getGBC( 0, 2, 5, 1, 1.0, 1.0, GridBagConstraints.BOTH );
	this.add( this.contentPanel, gbc );

	this.chessFrame.validate();
	this.chessFrame.repaint();
    }

    /**
     * shows the content of the actual games view
     */
    public final void setActGamesView()
    {
	this.bCenter.setEnabled( true );
	this.bDare.setEnabled( true );
	this.bMatches.setEnabled( false );
	this.bArchiv.setEnabled( true );

	this.remove( this.contentPanel );
	this.contentPanel = ChessFrame.actGamesViewPanel;

	GridBagConstraints gbc;
	gbc = GBCUtils.getGBC( 0, 2, 5, 1, 1.0, 1.0, GridBagConstraints.BOTH );
	this.add( this.contentPanel, gbc );

	this.chessFrame.validate();
	this.chessFrame.repaint();
    }

    /**
     * shows the content of the archived games view
     */
    public final void setArchGamesView()
    {
	this.bCenter.setEnabled( true );
	this.bDare.setEnabled( true );
	this.bMatches.setEnabled( true );
	this.bArchiv.setEnabled( false );

	this.remove( this.contentPanel );
	this.contentPanel = ChessFrame.archGamesViewPanel;

	GridBagConstraints gbc;
	gbc = GBCUtils.getGBC( 0, 2, 5, 1, 1.0, 1.0, GridBagConstraints.BOTH );
	this.add( this.contentPanel, gbc );

	this.chessFrame.validate();
	this.chessFrame.repaint();
    }
}
